package com.sinosoft.config.http;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
//import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfiguration {

    private Logger logger = LoggerFactory.getLogger(getClass());
    @Value("${http.persistconnecttimeout:30}")
    private int persistconnecttimeout;
    @Value("${http.maxpersistconnect:1000}")
    private int maxpersistconnect; //连接池的最大连接数默认为0
    @Value("${http.maxConnectPerRoute:1000}")
    private int maxConnectPerRoute; //单个主机的最大连接数
    @Value("${http.connectTimeout:2000}")
    private int connectTimeout; //连接超时默认2s
    @Value("${http.readTimeout:6000}")
    private int readTimeout; //读取超时默认30s

    /**
     * loadbalanced是使用ribbon对集群的服务进行调用 可以在这配置策略
     *
     * @return
     */
    @Bean
    //@LoadBalanced
    public RestTemplate restTmp(RestTemplateBuilder builder) {
        RestTemplate rt = builder.build();

        rt.setRequestFactory(clientHttpRequestFactory());

        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
        messageConverters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
        messageConverters.add(new FormHttpMessageConverter());
//        messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
        messageConverters.add(new MappingJackson2HttpMessageConverter());

        rt.setMessageConverters(messageConverters);
        rt.setErrorHandler(new DefaultResponseErrorHandler());

        logger.info("RestTemplate 初始化完成");
        return new RestTemplate();
    }

    @Bean
    public HttpClientConnectionManager poolingConnectionManager() {
        PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(persistconnecttimeout, TimeUnit.SECONDS);
        poolingConnectionManager.setMaxTotal(maxpersistconnect); // 连接池最大连接数  
        poolingConnectionManager.setDefaultMaxPerRoute(maxConnectPerRoute); // 每个主机的并发
        return poolingConnectionManager;
    }

    @Bean
    public HttpClientBuilder httpClientBuilder() {
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        //设置HTTP连接管理器
        httpClientBuilder.setConnectionManager(poolingConnectionManager());
        return httpClientBuilder;
    }

    @Bean
    public ClientHttpRequestFactory clientHttpRequestFactory() {
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        clientHttpRequestFactory.setHttpClient(httpClientBuilder().build());
        clientHttpRequestFactory.setConnectTimeout(connectTimeout); // 连接超时，毫秒		
        clientHttpRequestFactory.setReadTimeout(readTimeout); // 读写超时，毫秒		
        return clientHttpRequestFactory;
    }
}
